package com.lych.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.lych.autoconfig.template.HuanXinTemplate;
import com.lych.commons.utils.Constants;
import com.lych.dubbo.api.*;
import com.lych.model.domain.Question;
import com.lych.model.domain.User;
import com.lych.model.domain.UserInfo;
import com.lych.model.dto.RecommendUserDto;
import com.lych.model.mongo.RecommendUser;
import com.lych.model.mongo.SoulUser;
import com.lych.model.mongo.Visitors;
import com.lych.model.vo.ErrorResult;
import com.lych.model.vo.NearUserVo;
import com.lych.model.vo.PageResult;
import com.lych.model.vo.TodayBest;
import com.lych.server.exception.BusinessException;
import com.lych.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class TanhuaService {

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @Value("${tanhua.default.recommend.users}")
    private String recommendUser;

    @DubboReference
    private UserLikeApi userLikeApi;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private MessagesService messagesService;

    @DubboReference
    private UserLocationApi userLocationApi;

    @DubboReference
    private VisitorsApi visitorsApi;

    @DubboReference
    private SoulUserApi soulUserApi;

    /**
     * 今日佳人
     *
     * @return
     */
    public TodayBest todayBest() {
        //得到用户id
        Long userId = UserHolder.getUserId();
        //通过用户id查询今日佳人
        RecommendUser recommendUser = recommendUserApi.todayBest(userId);
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            recommendUser.setUserId(1l);
            recommendUser.setScore(99d);
        }

        //构建新用户测灵魂的问卷
        //查询目前有几套试题   这个参数1在实际中为一个内部测试账号，这里以1号用户代替。
        Integer size = soulUserApi.findSize(1L,UserHolder.getUserId());
        for (Integer i = 1; i <= size; i++) {
            SoulUser soulUser = new SoulUser();
            soulUser.setUserId(UserHolder.getUserId());
            soulUser.setSoulId(i.toString());
            if (i == 1) {
                soulUser.setIsLock(0);
            } else {
                soulUser.setIsLock(1);
            }
            soulUserApi.save(soulUser);
        }

        //通过今日佳人的id查询到具体信息，封装到TodayBest
        UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
        TodayBest vo = TodayBest.init(userInfo, recommendUser);
        return vo;
    }

    /**
     * 查询分页推荐好友列表
     *
     * @param dto
     * @return
     */
    public PageResult recommendation(RecommendUserDto dto) {
        //获得用户id
        Long userId = UserHolder.getUserId();
        //调用api进行分页查询
        PageResult pr = recommendUserApi.queryRecommendUser(dto.getPage(), dto.getPagesize(), userId);
        //拿到具体推荐好友的集合
        List<RecommendUser> items = (List<RecommendUser>) pr.getItems();
        //判断是否为空
        if (items == null) {
            return pr;
        }
        //获取所有推荐好友的id
        List<Long> ids = CollUtil.getFieldValues(items, "userId", Long.class);
        //根据条件，批量查询所有推荐用户的详细信息
        UserInfo userInfo = new UserInfo();
        userInfo.setAge(dto.getAge());
        userInfo.setGender(dto.getGender());
        Map<Long, UserInfo> map = userInfoApi.findByIds(ids, userInfo);
        //构建vo对象
        List<TodayBest> list = new ArrayList<>();
        for (RecommendUser item : items) {
            UserInfo info = map.get(item.getUserId());
            if (info != null) {
                TodayBest vo = TodayBest.init(info, item);
                list.add(vo);
            }
        }
        pr.setItems(list);
        return pr;

    }

    /**
     * 查看佳人信息
     *
     * @param userId 佳人id
     * @return
     */
    public TodayBest personalInfo(Long userId) {
        //根据佳人id查询佳人详细信息
        UserInfo userInfo = userInfoApi.findById(userId);
        //根据佳人id与操作人id查询两者的推荐数据
        RecommendUser recommendUser = recommendUserApi.queryById(userId, UserHolder.getUserId());

        //构造访客数据，调用api进行保存
        Visitors visitors = new Visitors();
        visitors.setFrom("首页");
        visitors.setDate(System.currentTimeMillis());
        visitors.setUserId(userId);
        visitors.setVisitorUserId(UserHolder.getUserId());
        visitors.setScore(recommendUser.getScore());
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        visitorsApi.save(visitors);

        //构建返回值
        return TodayBest.init(userInfo, recommendUser);
    }

    /**
     * 查询陌生人问题
     *
     * @param userId
     * @return
     */
    public String strangerQuestions(Long userId) {
        Question question = questionApi.findById(userId);
        return question == null ? "你喜欢超超嘛~~~~" : question.getTxt();
    }

    /**
     * 回复陌生人问题
     *
     * @param userId
     * @param reply
     * @return
     */
    public void replyQuestions(Long userId, String reply) {
        //构造消息数据
        Long id = UserHolder.getUserId();
        UserInfo userInfo = userInfoApi.findById(id);
        Map map = new HashMap();
        map.put("userId", id);
        map.put("huanXinId", Constants.HX_USER_PREFIX + id);
        map.put("strangerQuestion", strangerQuestions(userId));
        map.put("reply", reply);
        map.put("nickname", userInfo.getNickname());
        //转化为json
        String json = JSON.toJSONString(map);
        //调用对象，发送消息
        Boolean aBoolean = huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + userId, json);
        if(!aBoolean) {
            throw  new BusinessException(ErrorResult.error());
        }
    }

    /**
     * 探花-推荐用户列表
     * @return
     */
    public List<TodayBest> cards() {
        //调用api查询数据（排除喜欢/不喜欢，控制数量）
        List<RecommendUser> list = recommendUserApi.queryCardsList(UserHolder.getUserId(),10);
        //查看是否有数据，没有则构造默认数据
        if (CollUtil.isEmpty(list)) {
            list = new ArrayList<>();
            String[] ids = recommendUser.split(",");
            for (String userId : ids) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(Convert.toLong(userId));
                recommendUser.setToUserId(UserHolder.getUserId());
                recommendUser.setScore(RandomUtil.randomDouble(60, 90));
                list.add(recommendUser);
            }
        }
        //构造vo
        List<Long> ids = CollUtil.getFieldValues(list, "userId", Long.class);
        Map<Long, UserInfo> infoMap = userInfoApi.findByIds(ids, null);

        List<TodayBest> vos = new ArrayList<>();
        for (RecommendUser user : list) {
            UserInfo userInfo = infoMap.get(user.getUserId());
            if (userInfo != null) {
                TodayBest vo = TodayBest.init(userInfo,user);
                vos.add(vo);
            }
        }
        return vos;
    }

    /**
     * 探花-喜欢
     * @param likeUserId
     */
    public void idLove(Long likeUserId) {
        //调用api保存喜欢数据
        Boolean save = userLikeApi.idLove(UserHolder.getUserId(),likeUserId,true);
        if(!save) {
            //失败
            throw new BusinessException(ErrorResult.error());
        }
        //操作redis，写入喜欢的数据，删除不喜欢的数据 (喜欢的集合，不喜欢的集合)
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY+UserHolder.getUserId(), likeUserId.toString());
        redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY+UserHolder.getUserId(), likeUserId.toString());

        //判断是否双向喜欢
        if (islike(UserHolder.getUserId(),likeUserId)){
            //调用已经实现的方法添加好友关系
            messagesService.contacts(likeUserId);
        }
    }


    //判断是否双向喜欢
    private boolean islike(Long userId, Long likeUserId) {
        return redisTemplate.opsForSet().isMember(Constants.USER_LIKE_KEY+userId,likeUserId.toString());
    }

    /**
     * 探花-不喜欢
     * @param likeUserId
     */
    public void unlove(Long likeUserId) {
        //调用api保存不喜欢的数据
        Boolean aBoolean = userLikeApi.idLove(UserHolder.getUserId(), likeUserId, false);
        if(!aBoolean) {
            //失败
            throw new BusinessException(ErrorResult.error());
        }
        //操作redis，写入不喜欢的数据，删除喜欢的数据
        redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());
    }

    /**
     * 搜附近
     * @param gender
     * @param distance
     * @return
     */
    public List<NearUserVo> search(String gender, String distance) {
        //调用api查询当前用户附近的人
        List<Long> ids = userLocationApi.findNerUserId(UserHolder.getUserId(),Double.valueOf(distance));
        //非空判断
        if (CollUtil.isEmpty(ids)){
            return new ArrayList<>();
        }
        //根据id查询详细信息
        UserInfo user = new UserInfo();
        user.setGender(gender);
        Map<Long, UserInfo> infoMap = userInfoApi.findByIds(ids, user);
        //构造对象
        List<NearUserVo> vos = new ArrayList<>();
        for (Long id : ids) {
            //排除当前查询的用户
            if (id == UserHolder.getUserId()){
                continue;
            }
            UserInfo userInfo = infoMap.get(id);
            if (userInfo != null) {
                NearUserVo vo = NearUserVo.init(userInfo);
                vos.add(vo);
            }
        }
        return vos;
    }
}
